/*
 * Copyright (c) 2006-2019, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-09-09     WCH        the first version
 */
 
#include "board.h"
#include <stdint.h>
#include "drv_usart.h"
#include <rthw.h>
#include <rtthread.h>

extern uint32_t SystemCoreClock;

static uint32_t _SysTick_Config(rt_uint32_t ticks)
{
    NVIC_SetPriority(SysTicK_IRQn,0xf0);
    NVIC_SetPriority(Software_IRQn,0xf0);
    NVIC_EnableIRQ(SysTicK_IRQn);
    NVIC_EnableIRQ(Software_IRQn);
    SysTick->CTLR=0;
    SysTick->SR=0;
    SysTick->CNT=0;
    SysTick->CMP=ticks-1;
    SysTick->CTLR=0xF;
    return 0;
}

//#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
//#define RT_HEAP_SIZE (1024*16/4)
//static uint32_t rt_heap[RT_HEAP_SIZE];
//RT_WEAK void *rt_heap_begin_get(void)
//{
//    return rt_heap;
//}
//
//RT_WEAK void *rt_heap_end_get(void)
//{
//    return rt_heap + RT_HEAP_SIZE;
//}
//#endif


#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
void *rt_heap_begin_get(void)
{
    return HEAP_BEGIN;
}

void *rt_heap_end_get(void)
{
    return HEAP_END;
}
#endif




/**
 * This function will initial your board.
 */
void rt_hw_board_init()
{
    /* System Tick Configuration */
    _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
	
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
    /* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
    rt_hw_usart_init();
#endif
#ifdef RT_USING_CONSOLE
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
    /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

}

void LED1_BLINK_INIT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void SysTick_Handler(void)
{
    GET_INT_SP();
    /* enter interrupt */
    rt_interrupt_enter();
    SysTick->SR=0;
    rt_tick_increase();
    /* leave interrupt */
    rt_interrupt_leave();
    FREE_INT_SP();

}

#ifdef BSP_USING_UART
void ch32v307x_uart_gpio_init(USART_TypeDef  *uart_base)
{
    if(uart_base==USART1)
    {
        GPIO_InitTypeDef GPIO_InitStructure={0};
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
        /*
        * TXD PA9
        * RXD PA10
        **/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
    }
    if(uart_base==USART2)
    {
        GPIO_InitTypeDef GPIO_InitStructure={0};
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
        /*
        * TXD PA2
        * RXD PA3
        **/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

    }
    if(uart_base==USART3)
    {
        GPIO_InitTypeDef GPIO_InitStructure={0};
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
        /*
        * TXD PB10
        * RXD PB11
        **/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOB, &GPIO_InitStructure);

    }
    if(uart_base==UART4)
    {
        GPIO_InitTypeDef GPIO_InitStructure={0};
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
        /*
        * TXD PC10
        * RXD PC11
        **/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOC, &GPIO_InitStructure);

    }
    if(uart_base==UART5)
    {
        GPIO_InitTypeDef GPIO_InitStructure={0};
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
        /*
        * TXD PC12
        * RXD PD2
        **/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOD, &GPIO_InitStructure);
    }
    if(uart_base==UART6)
    {
        GPIO_InitTypeDef GPIO_InitStructure={0};
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART6, ENABLE);
        /*
        * TXD PC0
        * RXD PC1
        **/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOC, &GPIO_InitStructure);


//        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART6, ENABLE);
//        GPIO_PinRemapConfig( GPIO_PartialRemap_USART6, ENABLE);
//        /*
//        * TXD PB8
//        * RXD PB9
//        **/
//        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
//        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//        GPIO_Init(GPIOB, &GPIO_InitStructure);
//        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
//        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//        GPIO_Init(GPIOB, &GPIO_InitStructure);
    }
    if(uart_base==UART7)
    {
        GPIO_InitTypeDef GPIO_InitStructure={0};
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART7, ENABLE);
        /*
        * TXD PC2
        * RXD PC3
        **/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
    }
    if(uart_base==UART8)
    {
        GPIO_InitTypeDef GPIO_InitStructure={0};
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART8, ENABLE);
        /*
        * TXD PC4
        * RXD PC5
        **/
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOC, &GPIO_InitStructure);

    }
}
#endif


#ifdef BSP_USING_CAN
rt_weak void ch32v307x_can_gpio_init(CAN_TypeDef *can_base)
{
    GPIO_InitTypeDef GPIO_InitSturcture={0};
#ifdef BSP_USING_CAN1
    if (CAN1 == can_base)
    {
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE );
        RCC_APB1PeriphClockCmd( RCC_APB1Periph_CAN1, ENABLE );
        GPIO_PinRemapConfig( GPIO_Remap1_CAN1, ENABLE);
        /* CAN1 TXD --> PB9         CAN1 RXD --> PB8 */
        GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init( GPIOB, &GPIO_InitSturcture);
        GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_8;
        GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init( GPIOB, &GPIO_InitSturcture);

//        RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE );
//        RCC_APB1PeriphClockCmd( RCC_APB1Periph_CAN1, ENABLE );
//        /* CAN1 TXD --> PA12    CAN1 RXD --> PA11 */
//        GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_12;
//        GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
//        GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
//        GPIO_Init( GPIOA, &GPIO_InitSturcture);
//
//        GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_11;
//        GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_IPU;
//        GPIO_Init( GPIOA, &GPIO_InitSturcture);
    }
#endif
#ifdef BSP_USING_CAN2
    if (CAN2 == can_base)
    {
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE );
        RCC_APB1PeriphClockCmd( RCC_APB1Periph_CAN2, ENABLE );
        /* CAN2 TXD --> PB13        CAN2 RXD --> PB12 */
        GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_13;
        GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init( GPIOB, &GPIO_InitSturcture);
        GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_12;
        GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init( GPIOB, &GPIO_InitSturcture);

//        RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE );
//        RCC_APB1PeriphClockCmd( RCC_APB1Periph_CAN2, ENABLE );
//        GPIO_PinRemapConfig( GPIO_Remap_CAN2, ENABLE);
//        /* CAN2 TXD --> PB6        CAN2 RXD --> PB5 */
//        GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_6;
//        GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
//        GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
//        GPIO_Init( GPIOB, &GPIO_InitSturcture);
//        GPIO_InitSturcture.GPIO_Pin = GPIO_Pin_5;
//        GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_IPU;
//        GPIO_Init( GPIOB, &GPIO_InitSturcture);
    }
#endif
}
#endif /* BSP_USING_CAN */





